/************************************************************
 * Project Name		[Thinking_In_Java]
 * File Name     	[pkg_01_basic_grammar.Example_03_Operators.java]
 * Creation Date 	[12-Jun-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ************************************************************/
package pkg_01_basic_grammar;

/**
 * 运算符
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class Example_03_Operators {

	/**
	 * 算数运算符 +, -, *, /, %
	 * 
	 * @param a
	 *            左操作数
	 * @param b
	 *            右操作数
	 */
	public static void ArithmeticOperator(int a, int b) {

		int result = a + b;
		System.out.println("a + b = " + result);

		/*
		 * 当 * 号两边的数据类型为char, byte, short时, 其均会转换为int进行运算,
		 * 除此以外运算结果取决于两个操作数中范围较宽的类型
		 * 
		 * 当乘法运算产生的结果发生数据溢出时, 不会抛出ArithmeticException, 只会出现精度丢失的情况
		 */
		int multiplicationResult = a * b;
		System.out.println("a * b = " + multiplicationResult);

		/*
		 * 对于除法运算, 当 / 号两边数据类型为整型时, 结果为整型(不管其能否被除尽)
		 * 
		 * 当 / 号两边数据有一个是浮点型, 结果为浮点型
		 * 
		 * 如果左操作数为整型, 当 / 号的右操作数为0时, 会抛出ArithmeticException
		 * 
		 * 如果左操作数为浮点型, 当 / 号的右操作数为0时, 不会抛出异常
		 * 
		 * 常见结果有三种:Infinity; -Infinity; NaN
		 * 
		 * Infinity -> 2.0/0 Infinity -> -2.0/0 NaN -> 0.0/0;0.0/0.0;0/0.0
		 */
		int divisionResult = a / b;
		System.out.println("a / b = " + divisionResult);

		/*
		 * 判断是否为NaN
		 */
		System.out.println("0.0 / 0.0 is NaN: " + Double.isNaN(0.0 / 0.0));

		/*
		 * 对于取模运算: 实质是用左操作数连续减去右操作数, 直到相减的结果小于右操作数, 此时结果即为余数
		 * 
		 * 当取模运算中有负数作为操作数的时候, 取模运算结果的符号取决于左操作数的符号
		 * 
		 * 如果左操作数为整型, 当%符号的右操作数为0时, 会抛出ArithmeticException
		 * 
		 * 如果左操作数为浮点型, 当%符号右操作数为0时, 不会抛出异常,
		 * 
		 * NaN : 2.0%0; -2.0%0; 0.0%0; 0%0; 0%0.0
		 */
		int modResult = a % b;
		System.out.println("a % b = " + modResult);

	}

	/**
	 * 比较运算符: ==, !=, <, <=, >, >=,
	 * 
	 * @param a
	 *            左操作数
	 * @param b
	 *            右操作数
	 */
	public static void compareOperator(int a, int b) {
		System.out.println("a == b " + (a == b));
		System.out.println("a != b " + (a != b));
		System.out.println("a > b " + (a > b));
		System.out.println("a >= b " + (a >= b));
		System.out.println("a < b " + (a < b));
		System.out.println("a <= b " + (a <= b));
	}

	/**
	 * 位运算: &, |, ^, ~, >>, >>>, <<
	 * 
	 * @param a
	 *            左操作数
	 * @param b
	 *            右操作数
	 */
	public static void bitOperator(int a, int b) {

		/*
		 * 按位与, 两个操作数都为1时, 结果为1, 否则为0
		 */
		int c = a & b;
		System.out.println("按位与后: " + c);

		/*
		 * 按位或, 两个操作数都为0时, 结果为0, 否则为1
		 */
		c = a | b;
		System.out.println("按位或后: " + c);

		/*
		 * 按位异或, 两个操作数相同时结果为0, 不同时结果为1
		 */
		c = a ^ b;
		System.out.println("按位异或后: " + c);

		/*
		 * 按位非, 如果操作数为0, 则变成1, 如果为1, 则变成0
		 */
		c = ~a;
		System.out.println("按位非后: " + c);

		/*
		 * 左移 (<<) 低位补零, 高位舍弃, 其实质相当于乘以2的n次方
		 */
		c = a << b;
		System.out.println("左移后: " + c);

		/*
		 * 右移 (>>) 如果值为正: 高位补零, 低位舍弃, 如果值为负, 高位补1, 低位舍弃, 其实质相当于除以2的n次方
		 */
		c = a >> b;
		System.out.println("右移后: " + c);

		/*
		 * 无符号右移 (>>>) 不论正负与否, 高位补零, 低位舍弃
		 */
		c = a >>> b;
		System.out.println("无符号右移后: " + c);
	}

	/**
	 * 逻辑运算符: &, |, ^, !, &&, ||,
	 * 
	 * @param b1
	 *            参与逻辑运算的boolean表达式
	 * @param b2
	 *            参与逻辑运算的boolean表达式
	 * @param b3
	 *            参与逻辑运算的boolean表达式
	 */
	public static void booleanOperator(boolean b1, boolean b2, boolean b3) {
		/*
		 * 短路与运算: 如果第一个表达式结果为false, 那么整个表达式的结果就是false, 后面的表达式不再运算
		 */
		if (b1 && b2 && b3) {
			System.out.println("变量b1, b2, b3都为true");
		} else {
			System.out.println("变量b1, b2, b3至少有一个是false");
		}

		/*
		 * 短路或运算: 如果第一个表达式结果为true, 那么整个表达式的结果就是true, 后面的表达式不再运算
		 */
		if (b1 || b2 || b3) {
			System.out.println("变量b1, b2, b3至少有一个true");
		} else {
			System.out.println("变量b1, b2, b3都是false");
		}

		/*
		 * 异或运算: 操作数相同为false, 不同为true
		 */
		if (b1 ^ b2) {
			System.out.println("b1, b2的值不同");
		} else {
			System.out.println("b1, b2的值相同");
		}
	}

	/**
	 * 其他运算符
	 * 
	 * @param i
	 *            参与运算的变量
	 */
	public static void otherOperator(int i) {
		System.out.println(i++);
		System.out.println(++i);

		int x = (i > 0) ? i : -i;
		System.out.println(x);
	}

	/**
	 * 测试方法
	 * 
	 * @param args
	 *            命令行参数
	 */
	public static void main(String[] args) {
		int a = 7;
		int b = 5;
		Example_03_Operators.ArithmeticOperator(a, b);
		Example_03_Operators.compareOperator(a, b);
		Example_03_Operators.bitOperator(a, b);
		boolean b1 = true;
		boolean b2 = false;
		boolean b3 = true;
		Example_03_Operators.booleanOperator(b1, b2, b3);
		Example_03_Operators.otherOperator(7);

	}

}
